using System;
using System.Diagnostics;
using Headspring.Training.Domain.Model;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

namespace Headspring.Training.Domain.UnitTests.Model
{
	[TestFixture]
	public class EmployeeTester
	{
		[Test]
		public void PropertiesShouldInitializeProperly()
		{
			Employee employee = new Employee();
			Assert.That(employee.Id, Is.EqualTo(Guid.Empty));
			Assert.That(employee.UserName, Is.EqualTo(null));
			Assert.That(employee.FirstName, Is.EqualTo(null));
			Assert.That(employee.LastName, Is.EqualTo(null));
			Assert.That(employee.EmailAddress, Is.EqualTo(null));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Monday), Is.EqualTo(NotificationType.Both));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Tuesday), Is.EqualTo(NotificationType.Both));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Wednesday), Is.EqualTo(NotificationType.Both));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Thursday), Is.EqualTo(NotificationType.Both));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Friday), Is.EqualTo(NotificationType.Both));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Saturday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Sunday), Is.EqualTo(NotificationType.SMS));
		}

		[Test]
		public void ShouldBeAbleToSetSpecificNotificationPreferences()
		{
			Employee employee = new Employee();
			employee.SetNotificationPreferenceFor(DayOfWeek.Monday, NotificationType.Email);
			employee.SetNotificationPreferenceFor(DayOfWeek.Saturday, NotificationType.SMS);

			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Monday), Is.EqualTo(NotificationType.Email));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Saturday), Is.EqualTo(NotificationType.SMS));
		}

		[Test]
		public void ToStringShouldReturnFullName()
		{
			Employee employee = new Employee("", "Joe", "Camel", "");
			Assert.That(employee.ToString(), Is.EqualTo("Joe Camel"));
		}

        [Test]
        public void PropertiesShouldGetAndSetProperly()
        {
            Employee employee = new Employee();
            Guid guid = Guid.NewGuid();

            employee.EmailAddress = "Test";
            employee.FirstName = "Bob";
            employee.Id = guid;
            employee.LastName = "Joe";
            employee.UserName = "bobjoe";

            Assert.That(employee.EmailAddress, Is.EqualTo("Test"));
            Assert.That(employee.FirstName, Is.EqualTo("Bob"));
            Assert.That(employee.Id, Is.EqualTo(guid));
            Assert.That(employee.LastName, Is.EqualTo("Joe"));
            Assert.That(employee.UserName, Is.EqualTo("bobjoe"));
        }

        [Test]
        public void ConstructorSetsFieldsProperly()
        {
            Employee employee = new Employee("bobjoe", "Bob", "Joe", "Test");

            Assert.That(employee.EmailAddress, Is.EqualTo("Test"));
            Assert.That(employee.FirstName, Is.EqualTo("Bob"));
            Assert.That(employee.LastName, Is.EqualTo("Joe"));
            Assert.That(employee.UserName, Is.EqualTo("bobjoe"));
        }

        [Test]
        public void FullNameShouldCombineFirstAndLastName()
        {
            Employee employee = new Employee();

            employee.FirstName = "Bob";
            employee.LastName = "Joe";

            Assert.That(employee.GetFullName(), Is.EqualTo("Bob Joe"));
        }

		[Test]
		public void ShouldCompareEmployeesByLastName()
		{
			Employee employee1 = new Employee("", "1", "1", "");
			Employee employee2 = new Employee("", "1", "2", "");

			Assert.That(employee1.CompareTo(employee2), Is.EqualTo(-1));
			Assert.That(employee1.CompareTo(employee1), Is.EqualTo(0));
			Assert.That(employee2.CompareTo(employee1), Is.EqualTo(1));
		}
        
		[Test]
		public void ShouldCompareEmployeesByLastNameThenFirstName()
		{
			Employee employee1 = new Employee("", "1", "1", "");
			Employee employee2 = new Employee("", "2", "1", "");

			Assert.That(employee1.CompareTo(employee2), Is.EqualTo(-1));
			Assert.That(employee1.CompareTo(employee1), Is.EqualTo(0));
			Assert.That(employee2.CompareTo(employee1), Is.EqualTo(1));
		}

        [Test]
        [ExpectedExceptionAttribute("System.InvalidOperationException")]
        public void IsInvalidMobileNumber()
        {
            Employee employee1 = new Employee("","1","1","");
            employee1.MobileNumber = "abc";
            Assert.Fail();
        }

	    [Test]
	    public void IsValidMobileNumber()
	    {
            Employee employee1 = new Employee("", "1", "1", "");
	        employee1.MobileNumber = "123456789";
            Assert.That(employee1.MobileNumber, Is.EqualTo("123456789"));
	    }

		[Test]
		public void ShouldSetAllNotificationPreferences()
		{
			Employee employee = new Employee();
			employee.SetAllNotificationPreferencesTo(NotificationType.SMS);

			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Monday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Tuesday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Wednesday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Thursday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Friday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Saturday), Is.EqualTo(NotificationType.SMS));
			Assert.That(employee.GetNotificationTypeFor(DayOfWeek.Sunday), Is.EqualTo(NotificationType.SMS));
		}
	}
}
